import { BaseTool } from '../types';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
import * as path from 'path';

// 前向声明，避免循环导入
interface IToolManager {
    registerMCPRemoteTool(serverName: string, toolName: string, toolInfo: any): void;
    unregisterMCPRemoteTool(serverName: string, toolName?: string): void;
    updateSystemPromptAfterMCPConnection(): void;
}

interface MCPConnection {
    client: Client;
    transport: StdioClientTransport;
    serverName: string;
    connected: boolean;
}

// 内部MCP管理器，不暴露给AI
export class MCPManager {
    private connections: Map<string, MCPConnection> = new Map();
    private toolManagerRef: IToolManager | null = null;
    // 设置工具管理器引用
    setToolManagerRef(toolManager: IToolManager): void {
        this.toolManagerRef = toolManager;
    }

    // 连接到MCP服务器
    async connectToServer(serverName: string, command: string, cwd?: string): Promise<boolean> {
        if (!serverName || !command) {
            throw new Error('serverName和command参数是必需的');
        }
        if (this.connections.has(serverName)) {
            console.log(`⚠️ 服务器 "${serverName}" 已经连接`);
            return true;
        }

        try {
            // 解析命令 - 需要使用绝对路径
            const parts = command.trim().split(/\s+/);
            const executable = parts[0];
            const args = parts.slice(1);
            
            // 如果指定了工作目录，需要构建正确的命令路径
            let fullCommand = executable;
            if (cwd && !path.isAbsolute(executable)) {
                // 如果是相对路径的executable（如node），保持原样
                // 如果是相对路径的脚本，需要相对于cwd解析
                if (executable === 'node' || executable === 'python' || executable === 'python3') {
                    fullCommand = executable;
                } else {
                    fullCommand = path.resolve(cwd, executable);
                }
            }

            // 创建传输层 - 使用正确的参数格式
            const transport = new StdioClientTransport({
                command: fullCommand,
                args: args,
                cwd: cwd || process.cwd()
            });

            // 创建客户端
            const client = new Client({
                name: "mcp-tool-client",
                version: "1.0.0"
            }, {
                capabilities: {}
            });

            // 连接
            await client.connect(transport);

            // 存储连接
            this.connections.set(serverName, {
                client,
                transport,
                serverName,
                connected: true
            });

            // 获取服务器信息
            const serverInfo = await client.getServerCapabilities();
            
            // 自动注册远程工具到工具管理器
            if (this.toolManagerRef) {
                try {
                    const toolsResponse = await client.listTools();
                    if (toolsResponse.tools && toolsResponse.tools.length > 0) {
                        for (const tool of toolsResponse.tools) {
                            try {
                                this.toolManagerRef.registerMCPRemoteTool(serverName, tool.name, tool);
                            } catch (error) {
                                console.error(`Failed to register tool ${tool.name}:`, error);
                            }
                        }
                        // 关键：触发系统提示词更新
                        this.toolManagerRef.updateSystemPromptAfterMCPConnection();
                    }
                } catch (error) {
                    console.error('自动注册工具失败:', error);
                }
            }
            
            console.log(`✅ MCP服务器 "${serverName}" 连接成功，已注册 ${this.toolManagerRef ? 'remote tools' : '0'} 个远程工具`);
            return true;

        } catch (error: any) {
            console.error(`❌ 连接服务器失败: ${error.message}`);
            return false;
        }
    }

    // 断开连接
    async disconnectFromServer(serverName: string): Promise<void> {
        const connection = this.connections.get(serverName);
        if (!connection) {
            throw new Error(`服务器 "${serverName}" 未连接`);
        }

        try {
            await connection.client.close();
            this.connections.delete(serverName);
            
            // 移除相关的远程工具
            if (this.toolManagerRef) {
                this.toolManagerRef.unregisterMCPRemoteTool(serverName);
                this.toolManagerRef.updateSystemPromptAfterMCPConnection();
            }
            
            console.log(`✅ 已断开与服务器 "${serverName}" 的连接`);
        } catch (error: any) {
            throw new Error(`断开连接失败: ${error.message}`);
        }
    }

    // 调用远程工具
    async callRemoteTool(serverName: string, toolName: string, toolArgs?: any): Promise<string> {
        const connection = this.connections.get(serverName);
        if (!connection) {
            throw new Error(`服务器 "${serverName}" 未连接`);
        }

        try {
            const result = await connection.client.callTool({
                name: toolName,
                arguments: toolArgs || {}
            });

            let response = `🔧 远程工具调用结果\n\n`;
            response += `📡 服务器: ${serverName}\n`;
            response += `🛠️ 工具: ${toolName}\n`;
            response += `📋 参数: ${this.formatToolArgs(toolArgs || {})}\n\n`;
            response += `📤 结果:\n`;

            if (result.content && Array.isArray(result.content)) {
                result.content.forEach((item, index) => {
                    if (item.type === 'text') {
                        response += `${item.text}\n`;
                    } else {
                        response += `[${item.type}内容 #${index + 1}]\n`;
                    }
                });
            } else {
                response += JSON.stringify(result, null, 2);
            }

            return response;

        } catch (error: any) {
            throw new Error(`调用远程工具失败: ${error.message}`);
        }
    }

    // 格式化工具参数，避免HTML转义
    private formatToolArgs(args: Record<string, any>): string {
        try {
            // 使用自定义格式化，避免JSON.stringify的HTML转义
            return this.formatValue(args, 0);
        } catch (error) {
            return String(args);
        }
    }

    private formatValue(value: any, indent: number = 0): string {
        const spaces = '  '.repeat(indent);
        
        if (value === null) return 'null';
        if (value === undefined) return 'undefined';
        if (typeof value === 'string') {
            // 不进行HTML转义，保持原始字符串
            return `"${value}"`;
        }
        if (typeof value === 'number' || typeof value === 'boolean') {
            return String(value);
        }
        if (Array.isArray(value)) {
            if (value.length === 0) return '[]';
            const items = value.map(item => 
                `${spaces}  ${this.formatValue(item, indent + 1)}`
            ).join(',\n');
            return `[\n${items}\n${spaces}]`;
        }
        if (typeof value === 'object') {
            const keys = Object.keys(value);
            if (keys.length === 0) return '{}';
            const items = keys.map(key => 
                `${spaces}  "${key}": ${this.formatValue(value[key], indent + 1)}`
            ).join(',\n');
            return `{\n${items}\n${spaces}}`;
        }
        return String(value);
    }

    // 获取连接状态
    isConnected(serverName: string): boolean {
        return this.connections.has(serverName);
    }

    // 获取所有连接的服务器
    getConnectedServers(): string[] {
        return Array.from(this.connections.keys());
    }

    // 清理连接的方法
    async cleanup(): Promise<void> {
        for (const [name, connection] of this.connections) {
            try {
                await connection.client.close();
            } catch (error) {
                console.error(`Failed to close connection to ${name}:`, error);
            }
        }
        this.connections.clear();
    }
}

// 保留原来的MCPClientTool但简化为内部使用
export class MCPClientTool extends BaseTool {
    name = 'mcp-client-internal';
    description = '内部MCP客户端工具，不对AI暴露';
    parameters = {
        type: 'object' as const,
        properties: {
            action: {
                type: 'string',
                description: '内部操作类型'
            }
        },
        required: ['action']
    };


    private mcpManager: MCPManager = new MCPManager();

    // 设置工具管理器引用（在ToolManager中调用）
    setToolManagerRef(toolManager: IToolManager): void {
        this.mcpManager.setToolManagerRef(toolManager);
    }

    // 获取MCP管理器实例
    getMCPManager(): MCPManager {
        return this.mcpManager;
    }

    async execute(args: Record<string, any>): Promise<string> {
        // 这个方法现在主要用于内部操作，不对AI暴露
        return '内部MCP客户端工具';
    }

    // 清理连接的方法
    async cleanup(): Promise<void> {
        await this.mcpManager.cleanup();
    }
}